package cn.gson.oasys.aop;

import cn.gson.oasys.model.dao.log.LogTableDao;
import cn.gson.oasys.model.entity.monitor.Monitor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;


@Aspect
@Component
@RequestMapping("/")
public class logAspect {
    private Date date=new Date();
    //    private static String username1;
//    public void setUsername1(String username){
//        this.username1=username1;
//    }
//    public void getUser(String username){
//        this.username1=username1;
//    }




    @Resource
    private LogTableDao logTableDao;
    @Before("execution (* cn.gson.oasys.controller..*.*(..))")
    public void beforeAdvice(JoinPoint joinPoint){
        try {

            String operationType = "";
            String operateExplain = "";
            //获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息
            Signature signature = joinPoint.getSignature();
            //目标方法名
            String methodName = signature.getName();
            //目标方法所属类的简单类名
            String simpleName = signature.getDeclaringType().getSimpleName();

            //获取传入目标方法的参数对象
            Object target = joinPoint.getTarget();
            //获取当前请求参数
            MethodSignature methodSignature = (MethodSignature) signature;
            //获取当前代理类的全限定名
            String targetName = joinPoint.getTarget().getClass().getName();
            //获取当前请求路径
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String requestUrl = request.getRequestURL().toString();
            //获取请求ip
            String ipAddr = request.getRemoteHost();
            //System.out.println(requestUrl);
            //获取登录用户
//            SecurityContext context = SecurityContextHolder.getContext();
//            User principal = (User) context.getAuthentication().getPrincipal();
//            if(principal!=null) {
//                String username = principal.getUserName();
//                System.out.println(username+"===================================");
//            }

            //获取传入目标方法的参数对象
            Object[] args = joinPoint.getArgs();
            Class<?> aClass = null;
            try {
                aClass = Class.forName(targetName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            System.out.println("署名信息的对象:"+signature);
            System.out.println("目标方法所属类的简单类名:"+simpleName);
            System.out.println("获取传入目标方法的参数对象:"+target);
            System.out.println("代理类："+targetName);
            System.out.println("登录用户:"+"----------------------------------");
            System.out.println("方法名:"+methodName);
            System.out.println("操作类型:"+operationType);
            System.out.println("操作解释:"+operateExplain);
            System.out.println("请求路径:"+requestUrl);
            System.out.println("获取请求ip"+ipAddr);
            System.out.println("获取请求参数"+methodSignature);
            System.out.println("---------------------------开始保存日志----------------------------------");


            Monitor monitor1 = new Monitor();
            monitor1.setOperateClassName(targetName);      //方法所在类名
            monitor1.setOperateMethodName(methodName);     //执行的方法
            // logtable1.setOperateType(operationType);        //操作类型
            //logtable1.setOperateExplain(operateExplain);    //操作说明
            monitor1.setOperateUser("null"); // 操作人
            monitor1.setOperateDate(date);                 //执行的时间
            monitor1.setOperateIp(ipAddr);
            monitor1.setOperateResult("");
            monitor1.setOperateUrl(requestUrl);
            // logtable1.setRemark("");
            System.out.println(monitor1+"====================================");
            logTableDao.save(monitor1);
//            logTableDao.addLog(monitor1);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //异常通知
    @AfterThrowing(value = "execution (* cn.gson.oasys.controller..*.*(..))",throwing = "e")
    public void exceptionAdvice(JoinPoint joinPoint,Throwable e){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();
        //读取session中的用户
        Object user = session.getAttribute("user");
        //请求的IP
        String ip = request.getRemoteAddr();
        String params = "";
        if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
            params= Arrays.toString(joinPoint.getArgs());
        }
        System.out.println(params);
        try {
            // String operationType = "";
            //  String operateExplain = "";
            //获取传入目标方法的参数对象
            Object[] args = joinPoint.getArgs();
            //目标方法所属类的简单类名
            String simpleName = joinPoint.getSignature().getDeclaringType().getSimpleName();
            //获取方法名
            String methodName = joinPoint.getSignature().getName();
            //获取类的全限定名
            String targetName = joinPoint.getTarget().getClass().getName();

            System.out.println("---------------------------开始保存日志----------------------------------");
            // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-HH-dd hh:mm:ss");
            // String date = dateFormat.format(new Date());
            Monitor monitor1 = new Monitor();

            monitor1.setOperateClassName(targetName);      //方法所在类名
            System.out.println(targetName);
            monitor1.setOperateMethodName(methodName);     //执行的方法
            System.out.println(methodName);

            // logtable1.setOperateType(operationType);        //操作类型
            // logtable1.setOperateExplain(operateExplain);    //操作说明
            monitor1.setOperateUser("超级管理员");         //操作人
            monitor1.setOperateDate(date);                 //执行的时间

            monitor1.setOperateResult("删除失败,异常代码"+e.getClass().getName() +"异常信息："+e.getMessage());
            System.out.println(e.getClass().getName());
            System.out.println(e.getMessage());
            //logtable1.setRemark("");
            logTableDao.save(monitor1);
            System.out.println(monitor1);
            //logTableDao.addLog(monitor1);
        }catch (Exception ee){
            ee.printStackTrace();
        }
    }
}
